package root.service;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import net.arnx.jsonic.JSON;

import org.slim3.datastore.Datastore;
import org.slim3.memcache.MemcacheDelegate;
import org.slim3.util.ThrowableUtil;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Transaction;
import com.google.appengine.api.urlfetch.HTTPRequest;

import root.controller.administration.IndexController;
import root.meta.NoteMeta;
import root.model.Note;
import root.until.CacheInfo;
import root.until.UtilResolve;

public class OnetimeService {
    private MemcacheDelegate cache = new MemcacheDelegate();
    private static final Logger log = Logger.getLogger(OnetimeService.class
        .getName());
    NoteMeta meta = new NoteMeta();

    @SuppressWarnings("unchecked")
    public Note add(Map<String, Object> requestMap) {
        Note noteObj = new Note();
        // parse request data from client
        String subject = (String) requestMap.get("data[subject]");
        String content = (String) requestMap.get("data[content]");
        // Date time = (Date) requestMap.get("data[time]");
        // String start = (String) requestMap.get("data[start]");
        // String end = (String) requestMap.get("data[end]");
        String firstTitle = (String) requestMap.get("data[firstTitle]");
        String secondTitle = (String) requestMap.get("data[secondTitle]");
        String note = (String) requestMap.get("data[note]");
        String status = (String) requestMap.get("data[commonStatus]");
        String commonStatus = (String) requestMap.get("data[commonStatus]");
        log.info("value of subject " + subject);
        if (subject != null) {
            // set value for note object
            noteObj.setContent(content);
            noteObj.setCommonStatus(commonStatus);
            // noteObj.setStart(start);
            // noteObj.setEnd(end);
            noteObj.setSecondTitle(secondTitle);
            noteObj.setFirstTitle(firstTitle);
            noteObj.setNote(note);
            // noteObj.setTime(time);
            noteObj.setSubject(subject);
            noteObj.setStatus(status);
            // add data into datastore
            Transaction tx = Datastore.beginTransaction();
            try {
                Key noteKey = Datastore.put(noteObj);
                log.info(KeyFactory.keyToString(noteKey));
                noteObj.setKey(noteKey);
                tx.commit();
                // add data into cache
                // note object
                cache.put(
                    KeyFactory.keyToString(noteKey) + CacheInfo.NOTE,
                    noteObj,
                    CacheInfo.NOTE_CACHE_EXPIRATION);
                // list note
                List<Note> listNote =
                    (List<Note>) cache.get(CacheInfo.LIST_NOTE);
                if (listNote == null)
                    listNote = new ArrayList<Note>();
                listNote.add(noteObj);
                // put list into cache
                cache.put(
                    CacheInfo.LIST_NOTE,
                    listNote,
                    CacheInfo.NOTE_CACHE_EXPIRATION);
                log.info("update cache");
            } catch (Exception subE) {
                log.warning("commit update task fault");
                if (tx.isActive()) {
                    log.info("rollback transaction");
                    tx.rollback();
                }
                return null;
            }
        }

        return noteObj;
    }

    public Note edit(Map<String, Object> requestMap) {
        Note note = new Note();

        return note;
    }

    public boolean delete(Map<String, Object> requestMap) {
        boolean check = false;

        return check;
    }

    @SuppressWarnings("unchecked")
    public List<Note> getListNote() {
        // get list note from cache
        List<Note> rtList = (List<Note>) cache.get(CacheInfo.LIST_NOTE);
        if (rtList != null) {
            // load data from datastore
            rtList =
                Datastore.query(meta).filter(meta.delete.equal(false)).asList();
            // put data into cache
            cache.put(
                CacheInfo.LIST_NOTE,
                rtList,
                CacheInfo.NOTE_CACHE_EXPIRATION);
        }
        log.info("size of list " + rtList.size());
        return rtList;
    }

    /**
     * custom show date
     * */
    public Map<String, Object> formatDataResponse(int totalRecords,
            List<Note> element) {
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("iTotalRecords", totalRecords);
        data.put("iTotalDisplayRecords", totalRecords);
        int size = element.size();
        String[][] aaData = new String[size][9];
        int i = 0;
        Note noteElement = new Note();
        // Format formatter = new SimpleDateFormat("yyyy-MM-dd");
        // String s[];// for split function
        for (i = 0; i < size; i++) {
            noteElement = element.get(i);
            aaData[i][0] = String.valueOf(i + 1);
            aaData[i][1] = null;
            aaData[i][2] = null;
            aaData[i][3] = noteElement.getFirstTitle();
            aaData[i][4] = noteElement.getSecondTitle();
            aaData[i][5] = noteElement.getContent();
            aaData[i][6] = noteElement.getNote();
            aaData[i][7] =
                UtilResolve.getStatusString(noteElement.getCommonStatus());
            aaData[i][8] = UtilResolve.getStatusString(noteElement.getStatus());
        }
        data.put("aaData", aaData);
        return data;
    }
}
